#include "crypto_common.h"
#include <sys/stat.h>

// 测试实际的文件加密解密流程
void test_file_process_flow() {
    printf("=== 测试实际文件处理流程 ===\n");
    
    // 创建一个小的测试文件
    const char *test_file = "test_small_file.txt";
    const char *enc_file = "test_small_file.enc";
    const char *dec_file = "test_small_file_dec.txt";
    const char *key_file = "test_small_file.key";
    
    // 创建测试数据
    unsigned char test_data[100];
    for (int i = 0; i < 100; i++) {
        test_data[i] = (unsigned char)(i % 256);
    }
    
    // 写入测试文件
    FILE *fp = fopen(test_file, "wb");
    if (!fp) {
        printf("无法创建测试文件\n");
        return;
    }
    fwrite(test_data, 1, 100, fp);
    fclose(fp);
    
    printf("创建了100字节的测试文件\n");
    
    // === 模拟加密过程 ===
    printf("\n1. 模拟加密过程...\n");
    
    crypto_context_t encrypt_ctx;
    
    // 生成加密上下文（与encrypt.c完全相同）
    secure_random_init();
    encrypt_ctx.complexity_level = 3;
    generate_secure_random(encrypt_ctx.salt, SALT_LENGTH);
    encrypt_ctx.seed = (uint32_t)time(NULL) ^ (uint32_t)rand();
    
    // 使用密码生成主密钥
    const char *password = "10086";
    unsigned char hash_output[32];
    hash_function((const unsigned char*)password, strlen(password), hash_output);
    
    for (int i = 0; i < KEY_LENGTH; i++) {
        encrypt_ctx.primary_key[i] = hash_output[i % 32] ^ (unsigned char)(i * 37);
    }
    
    derive_keys(&encrypt_ctx);
    
    // 保存密钥文件
    FILE *fp_key = fopen(key_file, "wb");
    const char magic[] = "SECKEY01";
    fwrite(magic, 1, 8, fp_key);
    fwrite(&encrypt_ctx, sizeof(crypto_context_t), 1, fp_key);
    fclose(fp_key);
    
    // 加密文件
    FILE *fp_in = fopen(test_file, "rb");
    FILE *fp_out = fopen(enc_file, "wb");
    
    // 写入加密文件头
    const char header[] = "ENCRYPTED_FILE_V2";
    fwrite(header, 1, strlen(header), fp_out);
    fwrite(encrypt_ctx.salt, 1, SALT_LENGTH, fp_out);
    fwrite(&encrypt_ctx.seed, sizeof(uint32_t), 1, fp_out);
    fwrite(&encrypt_ctx.complexity_level, sizeof(uint8_t), 1, fp_out);
    
    long file_size = 100;
    fwrite(&file_size, sizeof(long), 1, fp_out);
    
    // 加密数据
    unsigned char buffer[100];
    fread(buffer, 1, 100, fp_in);
    
    printf("原始数据前16字节: ");
    for (int i = 0; i < 16; i++) printf("%02x ", buffer[i]);
    printf("\n");
    
    // 分块加密
    for (size_t i = 0; i < 100; i += BLOCK_SIZE) {
        size_t block_size = (i + BLOCK_SIZE <= 100) ? BLOCK_SIZE : (100 - i);
        advanced_encrypt_block(buffer + i, block_size, &encrypt_ctx);
    }
    
    printf("加密后前16字节: ");
    for (int i = 0; i < 16; i++) printf("%02x ", buffer[i]);
    printf("\n");
    
    fwrite(buffer, 1, 100, fp_out);
    fclose(fp_in);
    fclose(fp_out);
    
    printf("加密完成\n");
    
    // === 模拟解密过程 ===
    printf("\n2. 模拟解密过程...\n");
    
    crypto_context_t decrypt_ctx;
    
    // 加载密钥文件
    fp_key = fopen(key_file, "rb");
    char read_magic[9] = {0};
    fread(read_magic, 1, 8, fp_key);
    if (strcmp(read_magic, "SECKEY01") != 0) {
        printf("密钥文件格式错误\n");
        return;
    }
    fread(&decrypt_ctx, sizeof(crypto_context_t), 1, fp_key);
    fclose(fp_key);
    
    // 解密文件
    fp_in = fopen(enc_file, "rb");
    fp_out = fopen(dec_file, "wb");
    
    // 读取并验证文件头
    char file_header[18] = {0};
    fread(file_header, 1, 17, fp_in);
    if (strcmp(file_header, "ENCRYPTED_FILE_V2") != 0) {
        printf("加密文件格式错误\n");
        return;
    }
    
    // 读取加密参数
    unsigned char file_salt[SALT_LENGTH];
    uint32_t file_seed;
    uint8_t file_complexity;
    long original_size;
    
    fread(file_salt, 1, SALT_LENGTH, fp_in);
    fread(&file_seed, sizeof(uint32_t), 1, fp_in);
    fread(&file_complexity, sizeof(uint8_t), 1, fp_in);
    fread(&original_size, sizeof(long), 1, fp_in);
    
    printf("文件参数 - 大小:%ld, 种子:%u, 复杂度:%u\n", original_size, file_seed, file_complexity);
    
    // 使用文件中的参数更新上下文
    memcpy(decrypt_ctx.salt, file_salt, SALT_LENGTH);
    decrypt_ctx.seed = file_seed;
    decrypt_ctx.complexity_level = file_complexity;
    
    // 重新派生密钥（使用文件中的参数，不依赖随机数）
    derive_keys(&decrypt_ctx);
    
    printf("解密上下文已更新并重新派生密钥\n");
    
    // 验证密码
    unsigned char verify_hash[32];
    hash_function((const unsigned char*)password, strlen(password), verify_hash);
    unsigned char verify_key[KEY_LENGTH];
    for (int i = 0; i < KEY_LENGTH; i++) {
        verify_key[i] = verify_hash[i % 32] ^ (unsigned char)(i * 37);
    }
    
    if (memcmp(verify_key, decrypt_ctx.primary_key, KEY_LENGTH) == 0) {
        printf("密码验证成功\n");
    } else {
        printf("密码验证失败\n");
        return;
    }
    
    // 解密数据
    fread(buffer, 1, 100, fp_in);
    
    printf("解密前前16字节: ");
    for (int i = 0; i < 16; i++) printf("%02x ", buffer[i]);
    printf("\n");
    
    // 分块解密
    for (size_t i = 0; i < 100; i += BLOCK_SIZE) {
        size_t block_size = (i + BLOCK_SIZE <= 100) ? BLOCK_SIZE : (100 - i);
        advanced_decrypt_block(buffer + i, block_size, &decrypt_ctx);
    }
    
    printf("解密后前16字节: ");
    for (int i = 0; i < 16; i++) printf("%02x ", buffer[i]);
    printf("\n");
    
    fwrite(buffer, 1, 100, fp_out);
    fclose(fp_in);
    fclose(fp_out);
    
    printf("解密完成\n");
    
    // === 验证结果 ===
    printf("\n3. 验证结果...\n");
    
    // 读取解密后的文件
    fp = fopen(dec_file, "rb");
    unsigned char decrypted_data[100];
    fread(decrypted_data, 1, 100, fp);
    fclose(fp);
    
    // 比较
    int success = (memcmp(test_data, decrypted_data, 100) == 0);
    printf("文件内容比较: %s\n", success ? "✓ 完全一致" : "✗ 不一致");
    
    if (!success) {
        printf("前10个不匹配的字节:\n");
        int count = 0;
        for (int i = 0; i < 100 && count < 10; i++) {
            if (test_data[i] != decrypted_data[i]) {
                printf("位置 %d: 原始=0x%02x, 解密=0x%02x\n", i, test_data[i], decrypted_data[i]);
                count++;
            }
        }
    }
    
    // 清理文件
    remove(test_file);
    remove(enc_file);
    remove(dec_file);
    remove(key_file);
    
    printf("\n文件处理流程测试: %s\n", success ? "✓ 成功" : "✗ 失败");
}

int main() {
    test_file_process_flow();
    return 0;
}